home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / dsp / 56ktools / a5611.tz / a5611 / examples / chorus.a56 < prev    next >
Text File  |  1992-08-11  |  8KB  |  237 lines

  1. ;***************************************************************
  2. ; Stereo chorus for the DSP56001 signal processor.
  3. ; Developed by Quinn Jensen (jensenq@npd.novell.com).
  4. ; This program fragment implements a stereo "chorus" effect
  5. ; on a DSP56001 processor.  Chorus adds depth and warmth to
  6. ; sound by creating the illusion that more instruments
  7. ; are involved in the sound than really are.  It does this by
  8. ; mixing together a delayed version of the input with the input
  9. ; itself.  This program uses the following signal flow.
  10. ;
  11. ;
  12. ;  Left in ------+------- "dry" gain -----------> sum -----> Left out
  13. ;                |                                 ^
  14. ;                v                                 |
  15. ;               sum --> delay ---> "wet" gain -----+
  16. ;                ^                                 |
  17. ;                |                                 v -
  18. ;  Right in -----+------- "dry" gain -----------> sum -----> Right out
  19. ;
  20. ;
  21. ; Note that the delay line output is negated before summing with the
  22. ; right input signal.  This throws in 180 degrees of phase shift
  23. ; making for interesting results even with mono inputs 
  24. ; (i.e. Left in == Right in).
  25. ; Chorus uses a delay time of between about 10 and 50ms in some commercial
  26. ; units.  This program can be configured for longer delays.
  27. ; In the chorus effect, the delay time is slowly varied, adding a very
  28. ; subtle pitch shift.  The depth and speed of the delay-time modulation
  29. ; are adjustable to taste.  The greater the depth or speed, the greater
  30. ; the coloration of the signal.
  31. ;
  32. ; Variations in this algorithm are possible and encouraged.  I came
  33. ; up with this code after studying the impulse response and characteristics
  34. ; of a commercial stereo chorus pedal and reading various articles in magazines
  35. ; and on usenet over the years.  My somewhat dry TX81 synthesizer sounds pretty
  36. ; good with this and other effects I run on the 56001.
  37. ;
  38. ; A recent article with a pretty good not-too-technical overview of chorus 
  39. ; and other effects:  Gary Hall, "From the Top: Effects, the Essential Musical
  40. ; Spice," _Electronic Musician_, August 1991, pp. 62-68.
  41. ;
  42. ; I would enjoy seeing any improvements to the code.
  43. ;
  44. include 'tdsg.basic.a56'    ;hardware specific initialization code
  45.  
  46. ;***************************************************************
  47. ;
  48. ;    Data and constants
  49. ;
  50. ;***************************************************************
  51.  
  52. dot                ;remember where we were in P-space
  53.     org    x:$20        ;put runtime variables in on-chip X-space
  54.  
  55. ; A spreadsheet was used to calculate the following numbers
  56.  
  57. ; Sample rate              32.5500 kc         
  58. ; Delay time (4-52)        28.0000 ms        delay time knob
  59. ; Depth (1-10)             10.0000        depth knob (I like it deep)
  60. ; Speed (1-10)              0.0000        speed knob (I like it slow)
  61. ; max depth +/-            24.0000 ms         
  62. ; min delay                 4.0000 ms         
  63. ; max delay                52.0000 ms         
  64. ; 1/2 cycle period          5.0000 s          
  65. ; samples per 1/2 cyc  162750.0000
  66. ; time delta/samp           0.2949 us         
  67. ; offset samp/samp          0.0096
  68.   doff_i equ                              -130    ;initial delay offset (tap)
  69.   ddeltaf equ                           0.0096    ;delta-delay, per sample
  70.   dspeed_i equ                          162750    ;number of samples per
  71.                         ;half cycle of triangle wave
  72.                         ;delay-time modulator
  73. ; Delay time (ms)              tap                   tap     delay
  74. ;                   1      32.5500                     1      0.03
  75. ;                   2      65.1000                     2      0.06
  76. ;                   4     130.2000                     4      0.12
  77. ;                   5     162.7500                     8      0.25
  78. ;                   8     260.4000                    16      0.49
  79. ;                  10     325.5000                    32      0.98
  80. ;                  20     651.0000                    64      1.97
  81. ;                  25     813.7500                   128      3.93
  82. ;                  40    1302.0000                   256      7.86
  83. ;                  50    1627.5000                   512     15.73
  84. ;                  60    1953.0000                  1024     31.46
  85. ;                  70    2278.5000                  2048     62.92
  86. ;                  80    2604.0000                  4096    125.84
  87. ;                  90    2929.5000                  8192    251.67
  88. ;                 100    3255.0000                 16384    503.35
  89.  
  90. ;
  91. ;    The delay line is in off-chip X memory
  92. ;
  93. delay    equ    $2000
  94. dmax    equ    4096        ;125 ms (probably way too long)
  95. ;
  96. ; doff and ddelta are 48-bit quantities
  97. ;
  98. doff    dc    doff_i        ;current delay distance
  99.     org    y:doff
  100.     dc    0
  101.  
  102.     org    x:doff+1
  103. ddelta    dc    0        ;delta delay per sample
  104.     org    y:ddelta
  105.     dc    ddeltaf
  106.  
  107.     org    x:ddelta+1
  108.  
  109. dspeed    dc    dspeed_i    ;samples per half cycle of triangle modulator
  110. dtoggle    dc    0        ;current sample count
  111. delayout
  112.     dc    0        ;current delay-line output
  113.  
  114.     org    y:$0
  115.  
  116.     org    p:dot        ;go back to P-space
  117. ;***************************************************************
  118. ;
  119. ; Initialization code
  120. ;
  121. ;***************************************************************
  122. hf_init
  123.     move    #delay,r1            ;delay line input
  124.      movec    #dmax-1,m1            ;
  125.     move    #doff_i,n1            ;distance to output
  126.     rts
  127. ;
  128. ;***************************************************************
  129. ;
  130. ;    Sample-rate computations.  Call chorus_compute at
  131. ;    interrupt time when both left and right inputs are
  132. ;    ready.
  133. ;
  134. ;    fs = 32.552083 kHz
  135. ;
  136. ;    x:<in_l        left-channel input
  137. ;    x:<in_r        right-channel input
  138. ;    x:<out_l    left-channel output
  139. ;    x:<out_r    right-channel output
  140. ;
  141. ;***************************************************************
  142.  
  143. hf_comp
  144.     jsr    <saveregs
  145. ;
  146. ;    output and input mix
  147. ;
  148.     clr    a    #.4375,x1        ;clr a, get input scale
  149.     clr    b    #.5,y1            ;clr b, get output scaler
  150.  
  151.     move        x:<delayout,y0        ;get delay out
  152.  
  153.     macr    y0,y1,b    x:<in_l,x0        ;b = .5 * delay, x0=in_l
  154.     macr    x0,y1,b        b,y0           ;b += .5 * in_l, y0=b
  155.     macr    x0,x1,a b,x:<out_l        ;a = x1 * in_l, L = b
  156.     move            y0,b        ;b = -y0
  157.     neg    b    x:<in_r,x0        ;x0 = in_r
  158.     macr    x0,y1,b                ;b += .5 * in_r
  159.     macr    x0,x1,a    b,x:<out_r        ;R = b, a += x1 * in_r
  160. ;
  161. ;    delay line in
  162. ;
  163.     move    a,x:(r1)+
  164. ;
  165. ;    delay line length modulation.  A simple triangle-wave modulator
  166. ;    is used.  A sine-wave modulator would be much better, especially
  167. ;    with deeper and/or faster settings.
  168. ;
  169.     move        l:<doff,a        ;a = current offset
  170.     move        l:<ddelta,x        ;x = current delta
  171.     add    x,a
  172.     move        a,l:<doff        ;new offset = a + x
  173.     move        a1,n1
  174.  
  175.     move        x1,b            ;save delta for later use
  176. ;
  177. ; smoothly transition between delay-line offsets by
  178. ; interpolating the current sample with the previous or next
  179. ; one depending on whether the delay is currently getting longer or
  180. ; shorter.  Otherwise, an obnoxious click results when the offset snaps
  181. ; to the next integral value.  This does have a low-pass effect on the
  182. ; delayed signal path but it is not objectionable.
  183. ;
  184.     move            y:<doff,a    ;compute |frac(doff)|
  185.     lsr    a    #$800000,x0
  186.     or    x0,a    #.5,x1
  187.     move        a1,x0
  188.     mpy    -x0,x1,a
  189.     tst    b        a,y0        ;y0 = 0.5 * |frac(doff)|
  190.     jpl    shorter                ;on positive delta, the
  191.                         ;delay is shortening
  192.  
  193.     move        (r1)-            ;get previous sample
  194.     move        x:(r1+n1),x0
  195.     mpy    y0,x0,a    #.5,b            ;scale
  196.     sub    y0,b    (r1)+            ;compute scale for cur sample
  197.     move            b,y0
  198.     move        x:(r1+n1),x0        ;get cur sample
  199.     mac    x0,y0,a                ;scale and sum
  200.     jmp    endpan
  201.  
  202. shorter
  203.     move        x:(r1+n1),x0        ;get cur sample
  204.     mpy    y0,x0,a    #.5,b            ;scale
  205.     sub    y0,b    (r1)+            ;compute scale for next sample
  206.     move            b,y0
  207.     move        x:(r1+n1),x0        ;get next sample
  208.     mac    x0,y0,a    (r1)-            ;scale and sum
  209. endpan
  210.     move        a,x:<delayout        ;store resulting output
  211. ;
  212. ; update the triangle wave modulation (sinewave would be better)
  213. ;
  214.     move        x:<dtoggle,a        ;decrement toggle count
  215.     move        #>1,x0
  216.     sub    x0,a
  217.     move        a,x:<dtoggle
  218.     jgt    notogg                ;time to toggle?
  219.     move        x:<dspeed,x0        ;yes, negate delta and reset
  220.     move        l:<ddelta,a
  221.     neg    a    x0,x:<dtoggle
  222.     move        a,l:<ddelta
  223. notogg
  224. bypass
  225.     jsr    <restregs
  226.     rts
  227.  
  228.     end
  229.